package cn.fintecher.pangolin.service.dataimp.task;

import cn.fintecher.pangolin.common.enums.ImportDataExcelStatus;
import cn.fintecher.pangolin.common.enums.MessageType;
import cn.fintecher.pangolin.common.model.UserModel;
import cn.fintecher.pangolin.common.utils.ZWDateUtil;
import cn.fintecher.pangolin.entity.elastic.*;
import cn.fintecher.pangolin.entity.mysql.AssistCase;
import cn.fintecher.pangolin.entity.mysql.CaseInfo;
import cn.fintecher.pangolin.service.dataimp.elastic.*;
import cn.fintecher.pangolin.service.dataimp.model.ConfirmModel;
import cn.fintecher.pangolin.service.dataimp.repository.AssistCaseRepository;
import cn.fintecher.pangolin.service.dataimp.repository.CaseInfoRepository;
import cn.fintecher.pangolin.service.dataimp.service.BaseService;
import cn.fintecher.pangolin.common.utils.RepositoryUtil;
import org.apache.commons.collections4.IterableUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

/**
 * @Auther: xiaqun
 * @Description:
 * @Date: 14:58 2019/9/30
 */

@Service("confirmUpdateCaseTask")
public class ConfirmUpdateCaseTask {
    private static final Logger log = LoggerFactory.getLogger(ConfirmUpdateCaseTask.class);

    @Autowired
    private BaseCaseElastic baseCaseElastic;

    @Autowired
    private PersonalContactElastic personalContactElastic;

    @Autowired
    private PersonalAddressElastic personalAddressElastic;

    @Autowired
    private PersonalImportModelElastic personalImportModelElastic;

    @Autowired
    private DataImportRecordElastic dataImportRecordElastic;

    @Autowired
    private CaseInfoRepository caseInfoRepository;

    @Autowired
    private BaseService baseService;

    @Autowired
    private ConfirmCaseUpdateFuture confirmCaseUpdateFuture;

    @Autowired
    private AssistCaseRepository assistCaseRepository;

    /**
     * 案件更新确认
     */
    @Async
    @Transactional
    public void confirm(UserModel userModel, DataImportRecord record) {
        BoolQueryBuilder builder = new BoolQueryBuilder();
        builder.must(QueryBuilders.matchPhraseQuery("batchNumber.keyword", record.getBatchNumber()));
        Iterable<PersonalImportModel> importModels = personalImportModelElastic.search(builder);
        List<PersonalImportModel> models = IterableUtils.toList(importModels);
        //创建任务集合
        List<CompletableFuture<List<ConfirmModel>>> list = new ArrayList<>();
        //分页处理信息
        int pageSize = 2000;
        int pageNumber = (int) Math.ceil((double) models.size() / (double) pageSize);
        for (int i = 0; i < pageNumber; i++) {
            List<PersonalImportModel> personalImportModels = models.stream().skip(i * pageSize).limit(pageSize).collect(Collectors.toList());
            CompletableFuture<List<ConfirmModel>> task = confirmCaseUpdateFuture.processCase(personalImportModels, userModel);
            list.add(task);
        }
        List<ConfirmModel> confirmModels = new ArrayList<>();
        try {
            for (CompletableFuture<List<ConfirmModel>> future : list) {
                List<ConfirmModel> confirmModelList = future.get();
                confirmModels.addAll(confirmModelList);
            }
        } catch (InterruptedException | ExecutionException e) {
            log.error(e.getMessage(), e);
            record.setStatus(ImportDataExcelStatus.UN_CONFIRMED);
            record.process(userModel.getRealName(), ZWDateUtil.getNowDateTime());
            dataImportRecordElastic.save(record);
            baseService.sendMsg(MessageType.IMPORT_UPDATE_CONFIRMED, userModel);
        }
        List<BaseCase> baseCases = new ArrayList<>();
        List<PersonalContact> personalContacts = new ArrayList<>();
        List<PersonalAddress> personalAddresses = new ArrayList<>();
        List<CaseInfo> caseInfos = new ArrayList<>();
        List<AssistCase> assistCases = new ArrayList<>();
        confirmModels.forEach(e -> {
            baseCases.add(e.getBaseCase());
            if (Objects.nonNull(e.getCaseInfo())) {
                caseInfos.add(e.getCaseInfo());
            }
            if (Objects.nonNull(e.getPersonalContacts()) && !e.getPersonalContacts().isEmpty()) {
                personalContacts.addAll(e.getPersonalContacts());
            }
            if (Objects.nonNull(e.getPersonalAddresses()) && !e.getPersonalAddresses().isEmpty()) {
                personalAddresses.addAll(e.getPersonalAddresses());
            }
            if (Objects.nonNull(e.getAssistCases()) && !e.getAssistCases().isEmpty()) {
                assistCases.addAll(e.getAssistCases());
            }
        });
        if (!baseCases.isEmpty()) {
            RepositoryUtil.saveData(baseCaseElastic, baseCases);
        }
        if (!caseInfos.isEmpty()) {
            RepositoryUtil.saveData(caseInfoRepository, caseInfos);
        }
        if (!personalContacts.isEmpty()) {
            RepositoryUtil.saveData(personalContactElastic, personalContacts);
        }
        if (!personalAddresses.isEmpty()) {
            RepositoryUtil.saveData(personalAddressElastic, personalAddresses);
        }
        if (!assistCases.isEmpty()) {
            RepositoryUtil.saveData(assistCaseRepository, assistCases);
        }
        //删除导入模型
        RepositoryUtil.saveData(personalImportModelElastic, models);
        //更新导入结果状态
        record.setStatus(ImportDataExcelStatus.CONFIRMED);
        record.process(userModel.getRealName(), ZWDateUtil.getNowDateTime());
        dataImportRecordElastic.save(record);
        baseService.sendMsg(MessageType.IMPORT_UPDATE_CONFIRMED, userModel);
    }
}